﻿using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Ocelot.Cache;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
using Service.Framework;
using Service.Framework.Packet;
using Service.Gateway.Application.Service;
using System.Net;

namespace Service.Gateway.Core
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="cache"></param>
    public class DbServerFileConfigurationRepository(IOcelotCache<FileConfiguration> cache, IServiceProvider serviceProvider)
        : IFileConfigurationRepository
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<Response<FileConfiguration>> Get()
        {
            var config = cache.Get("FileConfiguration", "");
            if (config != null)
            {
                return new OkResponse<FileConfiguration>(config);
            }

            await using var asyncServiceScope = serviceProvider.CreateAsyncScope();
            IConfiguration configuration = asyncServiceScope.ServiceProvider.GetRequiredService<IConfiguration>();
            var gatewayService = asyncServiceScope.ServiceProvider.GetService<IGatewayService>();
            var gatewayList = await gatewayService.QueryApiGatewayList();
            var fileConfig = new FileConfiguration();

            var globalConfiguration = new FileGlobalConfiguration
            {
                DownstreamScheme = "http",
                LoadBalancerOptions = new FileLoadBalancerOptions() { Type = "RoundRobin" },
                RateLimitOptions = new FileRateLimitOptions()
                {
                    HttpStatusCode = (int)HttpStatusCode.TooManyRequests,
                    RateLimitCounterPrefix = "ocelot",
                    QuotaExceededMessage =
                        JsonConvert.SerializeObject(R.ResultData((int)HttpStatusCode.TooManyRequests, "访问过于频繁，请稍后重试")),
                },
                ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() { Type = configuration["ServiceDiscovery:Type"] },
            };
            fileConfig.GlobalConfiguration = globalConfiguration;
            List<FileRoute> fileRoutes = new List<FileRoute>();
            foreach (var gateway in gatewayList)
            {
                //注入每个网关服务得swagger
                var swagger = new FileRoute
                {
                    DownstreamPathTemplate = $"/swagger/v1/swagger.json",
                    ServiceName = gateway.RouteId,
                    UpstreamPathTemplate = $"/{gateway.RouteId}/swagger/v1/swagger.json",
                    UpstreamHttpMethod = [],
                    //DownstreamHeaderTransform = new Dictionary<string, string>
                    //{
                    //    ["X-Forwarded-For"] = "{RemoteIpAddress}",
                    //    ["X-Real-IP"] = "{RemoteIpAddress}"
                    //}
                };
                fileRoutes.Add(swagger);
                if (gateway.ServiceRoutes.Any())
                {
                    foreach (var route in gateway.ServiceRoutes)
                    {
                        var m = new FileRoute
                        {
                            DownstreamScheme = "http",
                            DownstreamPathTemplate = route.DownstreamPathTemplate,
                            ServiceName = gateway.RouteId,
                            UpstreamPathTemplate = route.UpstreamPathTemplate,
                            UpstreamHttpMethod = route.UpstreamHttpMethod,
                            UpstreamHeaderTransform = new Dictionary<string, string>
                            {
                                ["X-Forwarded-For"] = "{RemoteIpAddress}",
                                ["Location"] = "{DownstreamBaseUrl}, {BaseUrl}",
                                ["TraceId"] = "{TraceId}"
                            },
                            DangerousAcceptAnyServerCertificateValidator = true,
                        };
                        if (route.RateLimitOptions != null)
                            m.RateLimitOptions = route.RateLimitOptions;
                        fileRoutes.Add(m);
                    }
                }
            }

            fileConfig.Routes = fileRoutes;
            cache.AddAndDelete("FileConfiguration", fileConfig, TimeSpan.FromSeconds(1800), "");
            //返回配置信息
            return new OkResponse<FileConfiguration>(fileConfig);


        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileConfiguration"></param>
        /// <returns></returns>
        public async Task<Response> Set(FileConfiguration fileConfiguration)
        {
            cache.AddAndDelete("FileConfiguration", fileConfiguration, TimeSpan.FromSeconds(1800), "");
            return await Task.FromResult(new OkResponse());
        }
    }
}